package com.smartstate.dataManagement.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartstate.dataManagement.dto.*;
import com.smartstate.dataManagement.entity.Equipment;
import com.smartstate.dataManagement.entity.EquipmentConfiguration;
import com.smartstate.dataManagement.exception.ErrorEnums;
import com.smartstate.dataManagement.exception.MyRException;
import com.smartstate.dataManagement.mapper.AlarmMapper;
import com.smartstate.dataManagement.mapper.EquipmentConfigMapper;
import com.smartstate.dataManagement.mapper.EquipmentMapper;
import com.smartstate.dataManagement.mqtt.client.MyMQTTClient;
import com.smartstate.dataManagement.mqtt.common.GlobalMqttParam;
import com.smartstate.dataManagement.service.EquipmentConfigService;
import com.smartstate.dataManagement.util.SpringUtils;
import com.smartstate.dataManagement.vo.DeviceAlarmVO;
import com.smartstate.dataManagement.vo.DeviceAttributeVO;
import com.smartstate.dataManagement.vo.IssueIOTVO;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class EquipmentConfigImpl extends ServiceImpl<EquipmentConfigMapper, EquipmentConfiguration> implements EquipmentConfigService {

    @Autowired
    private EquipmentConfigMapper equipmentConfigMapper;

    @Autowired
    private EquipmentMapper equipmentMapper;

    @Autowired
    private AlarmMapper alarmMapper;

    @Override
    public Page<EquipmentConfiguration> queryAllPageByDTO(PageDTO pageDTO) {
        return null;
    }

    /**
     * MQTT连接配置
     */
    GlobalMqttParam globalMqttParam = SpringUtils.getBean(GlobalMqttParam.class);
    String broker = globalMqttParam.getBroker();
    String userName = globalMqttParam.getUserName();
    String passWord = globalMqttParam.getPassWord();
    String clientId1 = globalMqttParam.getSubClientId1() + System.currentTimeMillis();
    int keepalive = globalMqttParam.getKeepalive();
    int timeout = globalMqttParam.getTimeout();
    MyMQTTClient myMQTTClient = new MyMQTTClient(broker, userName, passWord, clientId1, keepalive, timeout);


    /**
     * 分页查询设备属性&&搜索设备属性
     *
     * @param pageDTO
     * @return
     */
    @Override
    public Page<DeviceAttributeVO> deviceAttribute(PageDTO<EquipmentDTO> pageDTO) {
        Page<DeviceAttributeVO> page = new Page<>();
        ArrayList<DeviceAttributeVO> deviceAttributes = new ArrayList<>();
        Equipment equipment = equipmentMapper.getOne(pageDTO.getDto().getDeviceId());
        //根据设备Id查询标签
        EquipmentConfiguration equipmentConfiguration = equipmentConfigMapper.selectOne(pageDTO.getDto().getDeviceId());
        List<EquipmentDTO.AddressData> addressDataPage = null;
        if (equipmentConfiguration != null && equipmentConfiguration.getTags() != null) {
            System.err.println(equipmentConfiguration.getTags());
            List<EquipmentDTO.AddressData> addressDataList = JSONArray.parseArray(equipmentConfiguration.getTags(), EquipmentDTO.AddressData.class);
            int offset = (int) ((pageDTO.getPage() - 1) * pageDTO.getSize());
            addressDataPage = addressDataList.subList(offset, addressDataList.size() > (int) (offset + pageDTO.getSize()) ? (int) (offset + pageDTO.getSize()) : addressDataList.size());
            for (EquipmentDTO.AddressData addressData : addressDataPage) {
                DeviceAttributeVO deviceAttribute = new DeviceAttributeVO();
                BeanUtils.copyProperties(addressData, deviceAttribute);
                deviceAttribute.setName(equipment.getName());
                deviceAttribute.setDeviceId(equipment.getDeviceId());
                deviceAttribute.setCreateTime(equipmentConfiguration.getCreateTime());
                deviceAttribute.setCreateUser(equipmentConfiguration.getCreateUser());
                deviceAttribute.setAttributeAlias(addressData.getAttributeAlias());
                deviceAttribute.setEnabled(addressData.getEnabled());
                //根据dataId查询模糊查询
                if (pageDTO.getDto().getDataId() != null) {
                    int[] ints = getkmpNext(addressData.getDataId());
                    int kmp = kmp(addressData.getDataId(), pageDTO.getDto().getDataId(), ints);
                    if (kmp != -1) {
                        deviceAttributes.add(deviceAttribute);
                    }
                }
                //根据属性名模糊查询
                 if (pageDTO.getDto().getAttributeAlias() != null) {
                    int[] ints = getkmpNext(addressData.getAttributeAlias());
                    int kmp = kmp(addressData.getAttributeAlias(), pageDTO.getDto().getAttributeAlias(), ints);
                    if (kmp != -1) {
                        deviceAttributes.add(deviceAttribute);
                    }
                }
//                //根据属性名和属性编码模糊搜索
//                else if (pageDTO.getDto().getAttributeAlias() != null && pageDTO.getDto().getDataId() != null) {
//                    int[] ints = getkmpNext(addressData.getDataId());
//                    int kmp = kmp(addressData.getDataId(), pageDTO.getDto().getDataId(), ints);
//
//                    int[] ints1 = getkmpNext(addressData.getAttributeAlias());
//                    int kmp1 = kmp(addressData.getAttributeAlias(), pageDTO.getDto().getAttributeAlias(), ints);
//
//                    if (kmp != -1 || kmp1 != -1) {
//                        deviceAttributes.add(deviceAttribute);
//                    }
//                }
                //根据启用禁用搜索
                 if (pageDTO.getDto().getEnabled() != null){
                    if (pageDTO.getDto().getEnabled().equals(deviceAttribute.getEnabled())){
                        deviceAttributes.add(deviceAttribute);
                    }
                }
                 if (pageDTO.getDto().getDataId() == null && pageDTO.getDto().getAttributeAlias() == null&& pageDTO.getDto().getEnabled() == null) {
                    deviceAttributes.add(deviceAttribute);
                }
            }
            //设置page属性
            HashSet<DeviceAttributeVO> objects = new HashSet<>(deviceAttributes);
            deviceAttributes.clear();
            deviceAttributes.addAll(objects);
            page.setRecords(deviceAttributes);
            page.setTotal(addressDataPage.size());
            long pages = (long) Math.ceil((double) addressDataPage.size() / page.getSize());
            page.setPages(pages);
            page.setSize(pageDTO.getSize());
            System.err.println(deviceAttributes);
        } else {
            //设置page属性
            page.setRecords(null);
            page.setTotal(0);
            page.setPages(0);
            page.setSize(pageDTO.getSize());
        }
        return page;
    }

    /**
     * 删除设备属性
     */
    @Override
    public Integer deleteDeviceAttribute(String deviceId, String attributeAlias) {
        EquipmentConfiguration equipmentConfiguration = equipmentConfigMapper.selectOne(deviceId);
        System.err.println(equipmentConfiguration.getTags());
        List<EquipmentDTO.AddressData> addressDataList = JSONArray.parseArray(equipmentConfiguration.getTags(), EquipmentDTO.AddressData.class);
        for (EquipmentDTO.AddressData addressData : addressDataList) {
            if (addressData.getAttributeAlias().equals(attributeAlias)) {
                addressDataList.remove(addressData);
                break;
            }
        }
        equipmentConfiguration.setTags(JSON.toJSONString(addressDataList));
        return equipmentConfigMapper.updateById(equipmentConfiguration);
    }

    /**
     * 添加设备属性
     *
     * @param deviceAttributeDTO
     * @return
     */
    @Override
    public int addDeviceAttribute(DeviceAttributeDTO deviceAttributeDTO) {
        //要保存的属性配置
        EquipmentConfiguration equipmentConfiguration = new EquipmentConfiguration();
        BeanUtils.copyProperties(deviceAttributeDTO, equipmentConfiguration);
        Equipment one = equipmentMapper.getOne(deviceAttributeDTO.getDeviceId());
        equipmentConfiguration.setType(one.getType());
        if (!CollectionUtils.isEmpty(deviceAttributeDTO.getAttributeList())) {
            //前端传过来的设备属性集合
            List<DeviceAttributeDTO.AddressData> attributeList = deviceAttributeDTO.getAttributeList();
            //数据库存的
            EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(deviceAttributeDTO.getDeviceId());
            //以前保存过设备的属性，就修改以前的tags
            if (configuration != null && !"".equals(configuration.getTags())) {
                //以前保存的属性配置
                List<DeviceAttributeDTO.AddressData> temporary = JSONArray.parseArray(configuration.getTags(), DeviceAttributeDTO.AddressData.class);
                HashSet<DeviceAttributeDTO.AddressData> objects = new HashSet<>(temporary);
                for (DeviceAttributeDTO.AddressData data : attributeList) {
                    data.setDataId(deviceAttributeDTO.getDeviceId() + "." + data.getDataId());
                    // 判断原来存的属性是否有重名的
                    for (DeviceAttributeDTO.AddressData addressData : objects) {
                        if (addressData.getAttributeAlias().equals(data.getAttributeAlias()) || addressData.getDataId().equals(data.getDataId())) {
                            throw new MyRException(ErrorEnums.CUSTOM);
                        }
                    }
                    data.setAttributeName(data.getDataId());
                    data.setEnabled(true);
                    objects.add(data);
                }
                //根据dataId获取属性名
//                objects.stream().forEach(data -> data.setAttributeName(data.getDataId().substring(data.getDataId().substring(0, data.getDataId().indexOf(".")).length() + 1, data.getDataId().length())));
//                for (DeviceAttributeDTO.AddressData object : objects) {
//                    object.setAttributeName(object.getDataId());
//                }
                equipmentConfiguration.setTags(JSON.toJSONString(objects));
                //根据id修改设备属性
                equipmentConfiguration.setId(configuration.getId());
                return equipmentConfigMapper.updateById(equipmentConfiguration);
            } else {
                Set<DeviceAttributeDTO.AddressData> endAttribute = new HashSet<>();
                //第一次新增设备的属性，就在数据库新增一条
                for (DeviceAttributeDTO.AddressData data : attributeList) {
                    data.setAttributeName(data.getDataId());
                    data.setDataId(deviceAttributeDTO.getDeviceId() + "." + data.getDataId());
                    data.setEnabled(true);
                    endAttribute.add(data);
                }
                HashSet<DeviceAttributeDTO.AddressData> objects = new HashSet<>(endAttribute);
//                objects.stream().forEach(data -> data.setAttributeName(data.getDataId().substring(data.getDataId().substring(0, data.getDataId().indexOf(".")).length() + 1, data.getDataId().length())));
//                for (DeviceAttributeDTO.AddressData object : objects) {
//                    String s = deviceAttributeDTO.getDeviceId() + "." + object.getDataId();
//                    object.setDataId(s);
//                }
                equipmentConfiguration.setTags(JSON.toJSONString(objects));
                equipmentConfiguration.setId(IdUtil.simpleUUID());
                return equipmentConfigMapper.insert(equipmentConfiguration);
            }

        } else {
            throw new MyRException(ErrorEnums.ATTRIBUTE_NO);
        }

    }

    /**
     * 编辑设备属性
     *
     * @param attributeDTO
     * @return
     */
    @Override
    public Integer updateDeviceAttribute(AttributeDTO attributeDTO) {
        String beforeDataId = "";
        String dataId = "";
        if ((attributeDTO.getDataId() != null) && (attributeDTO.getBeforeDataId() != null)) {
            beforeDataId = attributeDTO.getDeviceId() + "." + attributeDTO.getBeforeDataId();
            dataId = attributeDTO.getDeviceId() + "." + attributeDTO.getDataId();
        }

        EquipmentConfiguration equipmentConfiguration = equipmentConfigMapper.selectOne(attributeDTO.getDeviceId());
        //数据库中的tags
        List<EquipmentDTO.AddressData> addressDataList = JSONArray.parseArray(equipmentConfiguration.getTags(), EquipmentDTO.AddressData.class);
        //属性编码没变
        if ((dataId.equals(beforeDataId)) && !(attributeDTO.getAttributeAlias().equals(attributeDTO.getBeforeAttributeAlias()))) {
            for (EquipmentDTO.AddressData addressData : addressDataList) {
                if (addressData.getDataId().equals(dataId)) {
                    //根据属性别名查是否有存在的属性别名
                    EquipmentDTO.AddressData addressData2 = addressDataList.stream().filter(addressData1 -> addressData1.getAttributeAlias().equals(attributeDTO.getAttributeAlias())).findAny().orElse(null);
                    if (addressData2 == null) {
                        addressData.setAttributeAlias(attributeDTO.getAttributeAlias());
                        addressData.setPostProcessing(attributeDTO.getPostProcessing());
                        addressData.setAttributeName(attributeDTO.getDataId());
                    } else {
                        //属性别名已存在
                        throw new MyRException(ErrorEnums.CUSTOM);
                    }
                }
            }
        }

        //属性别名没变
        if ((attributeDTO.getAttributeAlias().equals(attributeDTO.getBeforeAttributeAlias())) && !((dataId.equals(beforeDataId)))) {
            for (EquipmentDTO.AddressData addressData : addressDataList) {
                if (addressData.getAttributeAlias().equals(attributeDTO.getAttributeAlias())) {
                    //根据属性编码查是否有存在的属性编码
                    EquipmentDTO.AddressData addressData2 = addressDataList.stream().filter(addressData1 -> addressData1.getDataId().equals(attributeDTO.getDeviceId() + "." + attributeDTO.getDataId())).findAny().orElse(null);
                    if (addressData2 == null) {
                        addressData.setDataId(dataId);
                        addressData.setPostProcessing(attributeDTO.getPostProcessing());
                        addressData.setAttributeName(attributeDTO.getDataId());
                    } else {
                        //属性别名已存在
                        throw new MyRException(ErrorEnums.CUSTOM);
                    }
                }

            }
        }

        //属性别名没变和属性编码没变
        if ((dataId.equals(beforeDataId)) && (attributeDTO.getAttributeAlias().equals(attributeDTO.getBeforeAttributeAlias()))) {
            for (EquipmentDTO.AddressData addressData : addressDataList) {
                if ((addressData.getDataId().equals(dataId)) || (addressData.getAttributeAlias().equals(attributeDTO.getAttributeAlias()))) {
                    addressData.setPostProcessing(attributeDTO.getPostProcessing());
                    addressData.setAttributeName(attributeDTO.getDataId());
                }
            }
        }

        //属性别名和属性编码都改变了
        if (!(dataId.equals(beforeDataId)) && !(attributeDTO.getAttributeAlias().equals(attributeDTO.getBeforeAttributeAlias()))) {
            for (EquipmentDTO.AddressData addressData : addressDataList) {
                if ((addressData.getDataId().equals(beforeDataId)) || (addressData.getAttributeAlias().equals(attributeDTO.getBeforeAttributeAlias()))) {
                    EquipmentDTO.AddressData data = addressDataList.stream().filter(addressData1 -> ((addressData1.getDataId().equals(attributeDTO.getDeviceId() + "." + attributeDTO.getDataId()) || addressData1.getAttributeAlias().equals(attributeDTO.getAttributeAlias())))).findAny().orElse(null);
                    if (data == null) {
                        addressData.setPostProcessing(attributeDTO.getPostProcessing());
                        addressData.setDataId(dataId);
                        addressData.setAttributeAlias(attributeDTO.getAttributeAlias());
                        addressData.setAttributeName(attributeDTO.getDataId());
                    } else {
                        throw new MyRException(ErrorEnums.CUSTOM);
                    }

                }
            }
        }
        String tags = JSON.toJSONString(addressDataList);
        equipmentConfiguration.setTags(tags);
        return equipmentConfigMapper.updateById(equipmentConfiguration);
    }


    /**
     * 设备报警属性分页
     *
     * @param pageDTO
     * @return
     */
    @Override
    public Page<DeviceAlarmVO> deviceAlarmPage(PageDTO<DeviceAlarmDTO> pageDTO) {
        //构造返回分页
        Page<DeviceAlarmVO> page = new Page<>();
        HashSet<DeviceAlarmVO> alarmVOS = new HashSet<>();
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(pageDTO.getDto().getDeviceId());
        if (configuration != null && configuration.getTags() != null) {
            //设备的属性集合
            List<EquipmentDTO.AddressData> temporary = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
            int offset = (int) ((pageDTO.getPage() - 1) * pageDTO.getSize());
            List<EquipmentDTO.AddressData> addressDataPage = temporary.subList(offset, temporary.size() > (int) (offset + pageDTO.getSize()) ? (int) (offset + pageDTO.getSize()) : temporary.size());
            for (EquipmentDTO.AddressData addressData : addressDataPage) {
                DeviceAlarmVO deviceAlarmVO = new DeviceAlarmVO();
                BeanUtils.copyProperties(addressData, deviceAlarmVO);
                alarmVOS.add(deviceAlarmVO);
            }
            //分页后的数据
            System.out.println(alarmVOS);
            ArrayList<DeviceAlarmVO> deviceAlarmVOS = new ArrayList<>();
            //根据属性名称和属性编码模糊搜索
            if (pageDTO.getDto().getAttributeAlias() != null && pageDTO.getDto().getDataId() != null) {
                for (DeviceAlarmVO alarmVO : alarmVOS) {
                    int[] ints = getkmpNext(alarmVO.getDataId());
                    int kmp = kmp(alarmVO.getDataId(), pageDTO.getDto().getDataId(), ints);

                    int[] ints1 = getkmpNext(alarmVO.getAttributeAlias());
                    int kmp1 = kmp(alarmVO.getAttributeAlias(), pageDTO.getDto().getAttributeAlias(), ints);

                    if (kmp != -1 || kmp1 != -1) {
                        deviceAlarmVOS.add(alarmVO);
                    }
                }
                if (!CollectionUtils.isEmpty(deviceAlarmVOS)) {
                    page.setRecords(deviceAlarmVOS);
                    page.setTotal(deviceAlarmVOS.size());
                }

            }
            //根据属性编码模糊搜索
            else if (pageDTO.getDto().getDataId() != null && pageDTO.getDto().getAttributeAlias() == null) {
                for (DeviceAlarmVO alarmVO : alarmVOS) {
                    int[] ints = getkmpNext(alarmVO.getDataId());
                    int kmp = kmp(alarmVO.getDataId(), pageDTO.getDto().getDataId(), ints);
                    if (kmp != -1) {
                        deviceAlarmVOS.add(alarmVO);
                    }
                }

                if (!CollectionUtils.isEmpty(deviceAlarmVOS)) {
                    page.setRecords(deviceAlarmVOS);
                    page.setTotal(deviceAlarmVOS.size());
                }
            }
            //根据属性别名模糊搜索
            else if (pageDTO.getDto().getAttributeAlias() != null && pageDTO.getDto().getDataId() == null) {
                for (DeviceAlarmVO alarmVO : alarmVOS) {
                    int[] ints = getkmpNext(alarmVO.getAttributeAlias());
                    int kmp = kmp(alarmVO.getAttributeAlias(), pageDTO.getDto().getAttributeAlias(), ints);
                    if (kmp != -1) {
                        deviceAlarmVOS.add(alarmVO);
                    }
                }
                if (!CollectionUtils.isEmpty(deviceAlarmVOS)) {
                    page.setRecords(deviceAlarmVOS);
                    page.setTotal(deviceAlarmVOS.size());
                }

            } else {
                page.setRecords(new ArrayList<>(alarmVOS));
                page.setTotal(alarmVOS.size());
            }
            long pages = (long) Math.ceil((double) addressDataPage.size() / page.getSize());
            page.setPages(pages);
            page.setSize(pageDTO.getSize());
        } else {
            long pages = 0;
            page.setPages(0);
            page.setSize(0);
//            page.setRecords(deviceAlarmVOS);
        }
        return page;

    }

    /**
     * 设备报警编辑  并下发给IOT
     *
     * @param deviceAlarmDTO
     * @return
     */
    @Override
    public Integer deviceAlarmEdit(DeviceAlarmDTO deviceAlarmDTO) throws MqttException {
        boolean s = true;
        //如果上下限和偏差的值相差甚远，就抛出异常
//        if ((Float.parseFloat(deviceAlarmDTO.getDown()) - Float.parseFloat(deviceAlarmDTO.getDeviation()) < 0) || (Float.parseFloat(deviceAlarmDTO.getUp()) - Float.parseFloat(deviceAlarmDTO.getDeviation()) < 0)) {
//            throw new MyRException(ErrorEnums.DEVIATION_NOT_REASONABLE);
//        }
        if (deviceAlarmDTO.getDeviation() != null && !"".equals(deviceAlarmDTO.getDeviation())) {
            //偏差超过上限
            if (deviceAlarmDTO.getUp() != null && !"".equals(deviceAlarmDTO.getUp()) && ((Float.parseFloat(deviceAlarmDTO.getUp()) - Float.parseFloat(deviceAlarmDTO.getDeviation()) < 0))) {
                throw new MyRException(ErrorEnums.DEVIATION_NOT_REASONABLE);
            }
            //偏差超过下限
            if (deviceAlarmDTO.getDown() != null && !"".equals(deviceAlarmDTO.getDown()) && ((Float.parseFloat(deviceAlarmDTO.getDown()) - Float.parseFloat(deviceAlarmDTO.getDeviation()) < 0))) {
                throw new MyRException(ErrorEnums.DEVIATION_NOT_REASONABLE);
            }
        }
        //下限大于上限
        if (deviceAlarmDTO.getDown() != null && !"".equals(deviceAlarmDTO.getDown()) && deviceAlarmDTO.getUp() != null && !"".equals(deviceAlarmDTO.getUp()) && (Float.parseFloat(deviceAlarmDTO.getDown()) > Float.parseFloat(deviceAlarmDTO.getUp()))) {
            throw new MyRException(ErrorEnums.DEVIATION_NOT_REASONABLE);
        }

        //设备的属性集合
        EquipmentConfiguration configuration = equipmentConfigMapper.selectOne(deviceAlarmDTO.getDeviceId());
        List<EquipmentDTO.AddressData> temporary = JSONArray.parseArray(configuration.getTags(), EquipmentDTO.AddressData.class);
        for (EquipmentDTO.AddressData addressData : temporary) {
            if (addressData.getDataId().equals(deviceAlarmDTO.getDataId())) {
                if ("0".equals(deviceAlarmDTO.getIsAlarm())) {
                    Date dates = new Date();
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
                    alarmMapper.updateAlarmAttributes(deviceAlarmDTO.getDeviceId(), addressData.getAttributeAlias(), "报警设置关闭", dateFormat.format(dates));
                }
                BeanUtils.copyProperties(deviceAlarmDTO, addressData);
            }
        }
        configuration.setTags(JSON.toJSONString(temporary));
        int i = equipmentConfigMapper.updateById(configuration);
        //通过MQTT下发给IOT
        if (configuration.getWay() != null && "box".equals(configuration.getWay())) {
            // 盒子采集方式
            box(deviceAlarmDTO);
        } else if (configuration.getWay() != null && "plc".equals(configuration.getWay())) {
            //plc采集方式
            plc(deviceAlarmDTO);
        }
        return i;
    }

    /**
     * 设备属性启用禁用
     *
     * @param attributeDTO
     * @return
     */
    @Override
    public Integer enabledAttribute(AttributeDTO attributeDTO) {
        //根据deviceId获取设备属性详情
        EquipmentConfiguration equipmentConfiguration = equipmentConfigMapper.selectOne(attributeDTO.getDeviceId());
        if (equipmentConfiguration != null && equipmentConfiguration.getTags() != null && !"".equals(equipmentConfiguration.getTags())) {
            String tags = equipmentConfiguration.getTags();
            List<EquipmentDTO.AddressData> addressDataList = JSONArray.parseArray(tags, EquipmentDTO.AddressData.class);
            addressDataList.stream().forEach(addressData -> {
                if (addressData.getAttributeAlias().equals(attributeDTO.getAttributeAlias())) {
                    addressData.setEnabled(attributeDTO.getEnabled());
                }
            });
            tags = JSON.toJSONString(addressDataList);
            equipmentConfiguration.setTags(tags);
            return equipmentConfigMapper.updateById(equipmentConfiguration);
        }
        return 0;
    }

    /**
     * 盒子的采集方式
     *
     * @param deviceAlarmDTO
     */
    private void box(DeviceAlarmDTO deviceAlarmDTO) {
        //通过MQTT下发给IOT
        try {
            ArrayList<Object> objects = new ArrayList<>();
            EquipmentDTO.AddressData addressData = new EquipmentDTO.AddressData();
            addressData.setDataId(deviceAlarmDTO.getDataId());  //设备编码
            addressData.setDeviation(deviceAlarmDTO.getDeviation());  //偏差
            addressData.setIsAlarm(deviceAlarmDTO.getIsAlarm()); //是否报警
            addressData.setUpLimit(deviceAlarmDTO.getUp());
            addressData.setDownLimit(deviceAlarmDTO.getDown());
            objects.add(addressData);
            String dataDonfiguration = JSON.toJSONString(objects);
            myMQTTClient.connect();
            myMQTTClient.publish(dataDonfiguration, "SH/NJ/HK/ALL/CONFIGS");
            System.out.println("MQTT消息发送成功");

        } catch (MqttException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * plc的采集方式
     *
     * @param deviceAlarmDTO
     */
    private void plc(DeviceAlarmDTO deviceAlarmDTO) throws MqttException {
        ArrayList<IssueIOTVO.AddressData> arrayList = new ArrayList<>();
        //通过MQTT下发给IOT
        IssueIOTVO issueIOT = new IssueIOTVO();
        issueIOT.setId(deviceAlarmDTO.getDeviceId());
        //上限
        if (deviceAlarmDTO.getUp() != null && !"".equals(deviceAlarmDTO.getUp())) {
            IssueIOTVO.AddressData addressData = new IssueIOTVO.AddressData();
            addressData.setAttributeName(deviceAlarmDTO.getDataId() + "up");
            addressData.setValue(deviceAlarmDTO.getUp());
            arrayList.add(addressData);
        }
        //下限
        if (deviceAlarmDTO.getDown() != null && !"".equals(deviceAlarmDTO.getDown())) {
            IssueIOTVO.AddressData addressData = new IssueIOTVO.AddressData();
            addressData.setAttributeName(deviceAlarmDTO.getDataId() + "down");
            addressData.setValue(deviceAlarmDTO.getDown());
            arrayList.add(addressData);
        }
        //是否报警
        if (deviceAlarmDTO.getIsAlarm() != null) {
            IssueIOTVO.AddressData addressData = new IssueIOTVO.AddressData();
            addressData.setAttributeName(deviceAlarmDTO.getDataId() + "IsAlarm");
            addressData.setValue("1".equals(deviceAlarmDTO.getIsAlarm()) ? "true" : "false");
            arrayList.add(addressData);
        }
        //补偿值
        if (deviceAlarmDTO.getDeviation() != null) {
            IssueIOTVO.AddressData addressData = new IssueIOTVO.AddressData();
            addressData.setAttributeName(deviceAlarmDTO.getDataId() + "Deviation");
            addressData.setValue(deviceAlarmDTO.getDeviation());
            arrayList.add(addressData);
        }


        String string = JSON.toJSONString(arrayList).toString();

        issueIOT.setWriteParameters(string);


        myMQTTClient.connect();
        myMQTTClient.publish(JSON.toJSONString(issueIOT), "SH/NJ/HK/PLC/CONFIGS");

    }


    /**
     * 模糊比较两个字符串  返回-1，比较失败，返回别的，比较成功
     *
     * @param str1
     * @param str2
     * @param next
     * @return
     */
    int kmp(String str1, String str2, int[] next) {
        int i1 = -1;
        for (int i = 0, j = 0; i < str1.length(); ++i) {

            while (j > 0 && str1.charAt(i) != str2.charAt(j)) {
                j = next[j - 1];
            }

            if (str1.charAt(i) == str2.charAt(j)) {
                j++;
            }

            if (j == str2.length()) {
                return i - j + 1;
            }
        }
        return -1;
    }


    /**
     * @return dest的部分匹配表
     */
    private static int[] getkmpNext(String dest) {
        int length = dest.length();
        int[] next = new int[length];
        next[0] = 0;

        for (int i = 1, j = 0; i < length; i++) {

            while (j > 0 && dest.charAt(i) != dest.charAt(j)) {
                j = next[j - 1];
            }

            if (dest.charAt(i) == dest.charAt(j)) {
                j++;
            }
            next[i] = j;
        }
        return next;
    }
}